home *** CD-ROM | disk | FTP | other *** search
/ Aminet 35 / Aminet 35 (2000)(Schatztruhe)[!][Feb 2000].iso / Aminet / dev / c / ascii2xxx.lha / ascii-2.7 / ascii.c next >
Encoding:
C/C++ Source or Header  |  1999-12-07  |  22.9 KB  |  637 lines

  1. /*
  2.  * ascii.c -- quick crossreference for ASCII character aliases
  3.  *
  4.  * by Eric S. Raymond <esr@snark.thyrsus.com>, v1.0 March 1990
  5.  *  v1.1 November 1990  -- revised `slang' from the 2.2 pronunciation guide
  6.  *  v1.2 March 1995     -- Fixed a core-dump bug
  7.  *  v1.3 October 1995   -- Fixed a bug that shows up only under ELF.
  8.  *  v2.0 December 1995  -- Interpret ISO-style code table escapes.
  9.  *  v2.1 August 1997    -- merge in changes by Ioannis Tambouras.
  10.  *  v2.2 November 1997  -- merge in more changes by Ioannis Tambouras.
  11.  *      v2.3 November 1997  -- incorporated Colin Plumb's splash-screen idea.
  12.  *  v2.4 December 1998  -- additions by Brian Ginsbach.
  13.  *  v2.5 December 1998  -- -s option by David N. Welton.
  14.  *  v2.6 June 1999      -- bug fixes by M.R. van Schouwen.
  15.  *  v2.7 October 1999   -- minor packaging and option changes.
  16.  *
  17.  * Tries to interpret arguments as names or aliases of ascii characters
  18.  * and dumps out *all* the aliases of each. Accepts literal characters,
  19.  * standard mnemonics, C-style backslash escapes, caret notation for control
  20.  * characters, numbers in hex/decimal/octal/binary, English names.
  21.  *
  22.  * The slang names used are selected from the 2.2 version of the USENET ascii
  23.  * pronunciation guide.  Some additional ones were merged in from the Jargon
  24.  * File.
  25.  *
  26.  * Reproduce, use, and modify this as you like, as long as you don't
  27.  * remove the authorship notice and clearly mark your changes. Send me
  28.  * your improvements, please.
  29.  */
  30.  
  31.  
  32. /* -------------------------------------------------------------------- */
  33. /* additions & porting to amigaos by Matthew J Fletcher 1999, for gcc,  */
  34. /* ixemul or amiga stuff, contact   amimjf@connectfree.co.uk   -thanks. */
  35. /*                                                                      */
  36. /* I just a cleaned the source to work with egcs 2.91 and fixed small   */
  37. /* bugs that must have got left in from somewhere.                      */
  38. /* -------------------------------------------------------------------- */
  39.  
  40.  
  41. #include <unistd.h>
  42. #include <stdio.h>
  43. #include <ctype.h>
  44. #include <string.h>
  45.  
  46. #define REVISION 2.7
  47.  
  48. typedef char    *string;
  49.  
  50. static unsigned char terse = 0;
  51. static unsigned char help = 0;
  52. static unsigned char line = 0;
  53.  
  54. enum { decimal, hex, octal } mode;
  55.  
  56. void print_table(unsigned short delivery);
  57.  
  58. static string cnames[128][15] =
  59. {
  60.     {"NUL",     "Null",         (char *)NULL},
  61.     {"SOH",     "Start Of Heading",     (char *)NULL},
  62.     {"STX",     "Start of Text",    (char *)NULL},
  63.     {"ETX",     "End of Text",      (char *)NULL},
  64.     {"EOT",     "End Of Transmission",  (char *)NULL},
  65.     {"ENQ",     "Enquiry",      (char *)NULL},
  66.     {"ACK",     "Acknowledge",      (char *)NULL},
  67.     {"BEL",     "Bell", "\\a", "Alert", (char *)NULL},
  68.     {"BS",      "Backspace", "\\b", (char *)NULL},
  69.     {"HT",  "TAB",  "Character Tabulation",
  70.                 "Horizontal Tab", "\\t", (char *)NULL},
  71.     {"LF",  "NL",   "Line Feed", "\\n", "Newline",  (char *)NULL},
  72.     {"VT",      "Line Tabulation",
  73.                 "Vertical Tab", "\\v", (char *)NULL},
  74.     {"FF",      "Form Feed", "\\f",     (char *)NULL},
  75.     {"CR",      "Carriage Return", "\\r",   (char *)NULL},
  76.     {"SO", "LS1",   "Shift Out", "Locking Shift 1", (char *)NULL},
  77.     {"SI", "LS0",   "Shift In", "Locking Shift 0",  (char *)NULL},
  78.     {"DLE",     "Data Link Escape", (char *)NULL},
  79.     {"DC1",     "Device Control 1", (char *)NULL},
  80.     {"DC2",     "Device Control 2", (char *)NULL},
  81.     {"DC3",     "Device Control 3", (char *)NULL},
  82.     {"DC4",     "Device Control 4", (char *)NULL},
  83.     {"NAK",     "Negative Acknowledge", (char *)NULL},
  84.     {"SYN",     "Synchronous Idle", (char *)NULL},
  85.     {"ETB",     "End of Transmission Block",    (char *)NULL},
  86.     {"CAN",     "Cancel",       (char *)NULL},
  87.     {"EM",      "End of Medium",    (char *)NULL},
  88.     {"SUB",     "Substitute",       (char *)NULL},
  89.     {"ESC",     "Escape",       (char *)NULL},
  90.     {"FS",      "File Separator",   (char *)NULL},
  91.     {"GS",      "Group Separator",  (char *)NULL},
  92.     {"RS",      "Record Separator", (char *)NULL},
  93.     {"US",      "Unit Separator",   (char *)NULL},
  94.     {" ", "SP",     "Space", "Blank",   (char *)NULL},
  95.     {"!",       "Exclamation Mark",
  96.                 "Bang", "Excl", "Wow", "Factorial", "Shriek",
  97.                 "Pling", "Smash", "Cuss", (char *)NULL},
  98.     {"\"",      "Quotation Mark",
  99.                 "Double Quote", "Quote", "String Quote",
  100.                 "Dirk", "Literal Mark", "Double Glitch",
  101.                 "# See ' and ` for matching names.",
  102.                 (char *)NULL},
  103.     {"#",       "Number Sign",
  104.                 "Pound", "Number", "Sharp", "Crunch", "Mesh",
  105.                 "Hex", "Hash", "Flash", "Grid", "Octothorpe",
  106.                 (char *)NULL},
  107.     {"$",       "Currency Sign",
  108.                 "Dollar", "Buck", "Cash", "Ding",
  109.                 (char *)NULL},
  110.     {"%",       "Percent Sign",
  111.                 "Mod", (char *)NULL},
  112.     {"&",       "Ampersand",
  113.                 "Amper", "And", (char *)NULL},
  114.     {"'",       "Apostrophe",
  115.                 "Single Quote", "Close Quote",  "Prime",
  116.                 "Tick", "Pop", "Spark", "Glitch",
  117.                 "# See ` and \" for matching names.",
  118.                 (char *)NULL},
  119.     {"(",       "Left Parenthesis",
  120.                 "Open", "Open Paren",
  121.                 "Left Paren", "Wane", "Sad",
  122.                 "# See `)' for matching names.",
  123.                 (char *)NULL},
  124.     {")",       "Right Parenthesis",
  125.                 "Close", "Close Paren",
  126.                 "Right Paren", "Wax", "Happy",
  127.                 "# See `(' for matching names.",
  128.                  (char *)NULL},
  129.     {"*",       "Asterisk",
  130.                 "Star", "Splat", "Aster", "Times", "Gear",
  131.                 "Dingle", "Bug", "Twinkle", "Glob",  
  132.                 (char *)NULL},
  133.     {"+",       "Plus Sign",
  134.                 "Add", "Cross", (char *)NULL},
  135.     {",",       "Comma",
  136.                 "Tail", (char *)NULL},
  137.     {"-",       "Hyphen",
  138.                 "Dash", "Minus", "Worm", (char *)NULL}, 
  139.     {".",       "Full Stop",
  140.                 "Dot", "Decimal Point", "Radix Point",
  141.                 "Point", "Period", "Spot", (char *)NULL},
  142.     {"/",       "Solidus",
  143.                 "Slash", "Stroke", "Slant", "Diagonal",
  144.                 "Virgule", "Over", "Slat",
  145.                 "# See `\\' for matching names.",
  146.                 (char *)NULL},
  147.     {"0",       "Digit Zero", (char *)NULL},
  148.     {"1",       "Digit One", (char *)NULL},
  149.     {"2",       "Digit Two", (char *)NULL},
  150.     {"3",       "Digit Three", (char *)NULL},
  151.     {"4",       "Digit Four", (char *)NULL},
  152.     {"5",       "Digit Five", (char *)NULL},
  153.     {"6",       "Digit Six", (char *)NULL},
  154.     {"7",       "Digit Seven", (char *)NULL},
  155.     {"8",       "Digit Eight", (char *)NULL},
  156.     {"9",       "Digit Nine", (char *)NULL},
  157.     {":",       "Colon",
  158.                 "Double-Dot", (char *)NULL},
  159.     {";",       "Semicolon",
  160.                 "Semi", "Go-on", (char *)NULL},
  161.     {"<",       "Less-than Sign",
  162.                 "Left Angle Bracket", "Read From", "In",
  163.                 "From", "Comesfrom", "Left Funnel",
  164.                 "Left Broket", "Crunch", "Suck",
  165.                 "# See `<' for matching names.",
  166.                  (char *)NULL},
  167.     {"=",       "Equals Sign",
  168.                 "Quadrathorp", "Gets", "Becomes", "Half-Mesh",
  169.                 (char *)NULL},
  170.     {">",       "Greater-than sign",
  171.                 "Right Angle" , "Write To", "Into", "Toward",
  172.                 "Out", "To", "Gozinta", "Right Funnel",
  173.                 "Right Broket", "Zap", "Blow",
  174.                 "# See `>' for matching names.",
  175.                  (char *)NULL},
  176.     {"?",       "Question Mark",
  177.                 "Whatmark", "What", "Ques", (char *)NULL},
  178.     {"@",       "Commercial At",
  179.                 "At", "Each", "Vortex", "Whorl", "Whirlpool",
  180.                 "Cyclone", "Snail", "Rose", (char *)NULL},
  181.     {"A",       "Majuscule A", "Capital A", "Uppercase A",(char*)NULL},
  182.     {"B",       "Majuscule B", "Capital B", "Uppercase B",(char*)NULL},
  183.     {"C",       "Majuscule C", "Capital C", "Uppercase C",(char*)NULL},
  184.     {"D",       "Majuscule D", "Capital D", "Uppercase D",(char*)NULL},
  185.     {"E",       "Majuscule E", "Capital E", "Uppercase E",(char*)NULL},
  186.     {"F",       "Majuscule F", "Capital F", "Uppercase F",(char*)NULL},
  187.     {"G",       "Majuscule G", "Capital G", "Uppercase G",(char*)NULL},
  188.     {"H",       "Majuscule H", "Capital H", "Uppercase H",(char*)NULL},
  189.     {"I",       "Majuscule I", "Capital I", "Uppercase I",(char*)NULL},
  190.     {"J",       "Majuscule J", "Capital J", "Uppercase J",(char*)NULL},
  191.     {"K",       "Majuscule K", "Capital K", "Uppercase K",(char*)NULL},
  192.     {"L",       "Majuscule L", "Capital L", "Uppercase L",(char*)NULL},
  193.     {"M",       "Majuscule M", "Capital M", "Uppercase M",(char*)NULL},
  194.     {"N",       "Majuscule N", "Capital N", "Uppercase N",(char*)NULL},
  195.     {"O",       "Majuscule O", "Capital O", "Uppercase O",(char*)NULL},
  196.     {"P",       "Majuscule P", "Capital P", "Uppercase P",(char*)NULL},
  197.     {"Q",       "Majuscule Q", "Capital Q", "Uppercase Q",(char*)NULL},
  198.     {"R",       "Majuscule R", "Capital R", "Uppercase R",(char*)NULL},
  199.     {"S",       "Majuscule S", "Capital S", "Uppercase S",(char*)NULL},
  200.     {"T",       "Majuscule T", "Capital T", "Uppercase T",(char*)NULL},
  201.     {"U",       "Majuscule U", "Capital U", "Uppercase U",(char*)NULL},
  202.     {"V",       "Majuscule V", "Capital V", "Uppercase V",(char*)NULL},
  203.     {"W",       "Majuscule W", "Capital W", "Uppercase W",(char*)NULL},
  204.     {"X",       "Majuscule X", "Capital X", "Uppercase X",(char*)NULL},
  205.     {"Y",       "Majuscule Y", "Capital Y", "Uppercase Y",(char*)NULL},
  206.     {"Z",       "Majuscule Z", "Capital Z", "Uppercase Z",(char*)NULL},
  207.     {"[",       "Left Square Bracket",
  208.                 "Bracket", "Bra", "Square",
  209.                 "# See `]' for matching names.",
  210.                  (char *)NULL},
  211.     {"\\",      "Reversed Solidus",
  212.                 "Backslash", "Bash", "Backslant", "Backwhack",
  213.                 "Backslat", "Literal", "Escape",
  214.                 "# See `/' for matching names.",
  215.                  (char *)NULL},
  216.     {"]",       "Right Square Bracket",
  217.                 "Unbracket", "Ket", "Unsquare",
  218.                 "# See `]' for matching names.",
  219.                  (char *)NULL},
  220.     {"^",       "Circumflex Accent",
  221.                 "Circumflex", "Caret", "Uparrow", "Hat",
  222.                 "Control", "Boink", "Chevron", "Hiccup",
  223.                 "Sharkfin", "Fang", (char*)NULL},
  224.     {"_",       "Low Line",
  225.                 "Underscore", "Underline", "Underbar",
  226.                 "Under", "Score", "Backarrow", "Flatworm", 
  227.     "# `Backarrow' refers to this character's graphic in 1963 ASCII.",
  228.                 (char*)NULL},
  229.     {"`",       "Grave Accent",
  230.                 "Grave", "Backquote", "Left Quote",
  231.                 "Open Quote", "Backprime", "Unapostrophe",
  232.                 "Backspark", "Birk", "Blugle", "Back Tick",
  233.                 "Push",
  234.                 "# See ' and \" for matching names.",
  235.                 (char *)NULL},
  236.     {"a",       "Miniscule a", "Small a", "Lowercase a",(char*)NULL},
  237.     {"b",       "Miniscule b", "Small b", "Lowercase b",(char*)NULL},
  238.     {"c",       "Miniscule c", "Small c", "Lowercase c",(char*)NULL},
  239.     {"d",       "Miniscule d", "Small d", "Lowercase d",(char*)NULL},
  240.     {"e",       "Miniscule e", "Small e", "Lowercase e",(char*)NULL},
  241.     {"f",       "Miniscule f", "Small f", "Lowercase f",(char*)NULL},
  242.     {"g",       "Miniscule g", "Small g", "Lowercase g",(char*)NULL},
  243.     {"h",       "Miniscule h", "Small h", "Lowercase h",(char*)NULL},
  244.     {"i",       "Miniscule i", "Small i", "Lowercase i",(char*)NULL},
  245.     {"j",       "Miniscule j", "Small j", "Lowercase j",(char*)NULL},
  246.     {"k",       "Miniscule k", "Small k", "Lowercase k",(char*)NULL},
  247.     {"l",       "Miniscule l", "Small l", "Lowercase l",(char*)NULL},
  248.     {"m",       "Miniscule m", "Small m", "Lowercase m",(char*)NULL},
  249.     {"n",       "Miniscule n", "Small n", "Lowercase n",(char*)NULL},
  250.     {"o",       "Miniscule o", "Small o", "Lowercase o",(char*)NULL},
  251.     {"p",       "Miniscule p", "Small p", "Lowercase p",(char*)NULL},
  252.     {"q",       "Miniscule q", "Small q", "Lowercase q",(char*)NULL},
  253.     {"r",       "Miniscule r", "Small r", "Lowercase r",(char*)NULL},
  254.     {"s",       "Miniscule s", "Small s", "Lowercase s",(char*)NULL},
  255.     {"t",       "Miniscule t", "Small t", "Lowercase t",(char*)NULL},
  256.     {"u",       "Miniscule u", "Small u", "Lowercase u",(char*)NULL},
  257.     {"v",       "Miniscule v", "Small v", "Lowercase v",(char*)NULL},
  258.     {"w",       "Miniscule w", "Small w", "Lowercase w",(char*)NULL},
  259.     {"x",       "Miniscule x", "Small x", "Lowercase x",(char*)NULL},
  260.     {"y",       "Miniscule y", "Small y", "Lowercase y",(char*)NULL},
  261.     {"z",       "Miniscule z", "Small z", "Lowercase z",(char*)NULL},
  262.     {"{",       "Left Curly Bracket",
  263.                 "Left Brace", "Brace", "Open Brace",
  264.                 "Curly", "Leftit", "Embrace",
  265.                 "# See `}' for matching names.",
  266.                  (char *)NULL},
  267.     {"|",       "Vertical Line",
  268.                 "Pipe", "Bar", "Or", "V-Bar", "Spike",
  269.                 "Gozinta", "Thru", (char *)NULL},
  270.     {"}",       "Right Curly Bracket",
  271.                 "Right Brace", "Unbrace", "Close Brace",
  272.                 "Uncurly", "Rytit", "Bracelet",
  273.                 "# See `{' for matching names.",
  274.                  (char *)NULL},
  275.     {"~",       "Overline",
  276.                 "Tilde", "Swung Dash", "Squiggle", "Approx",
  277.                 "Wiggle", "Twiddle", "Enyay", (char *)NULL},
  278.     {"DEL",     "Delete", (char *)NULL},
  279. };
  280. /******************************************************************/
  281. static int atob(str)
  282. /* ASCII-to-binary conversion */
  283. char    *str;
  284. {
  285.     int val;
  286.  
  287.     for (val = 0; *str; str++)
  288.     {
  289.     val *= 2;
  290.  
  291.     if (*str == '1')
  292.         val++;
  293.         else if (*str != '0')
  294.         return(-1);
  295.     }
  296.     return(val);
  297. }
  298.  
  299. /*********************************************************/
  300. void 
  301. showHelp(FILE *out, char *progname) 
  302. {
  303.   fprintf(out,"Usage: %s [-dxohv] [-t] [char-alias...]\n", progname); 
  304. #define P(s)    puts(s);
  305. //#include "splashscreen.h"
  306. #undef P
  307.  
  308.   exit(0);
  309. }
  310.  
  311. /*********************************************************/
  312. void 
  313. process_options(int argc, char *argv[], char * opt_string) 
  314. {
  315.     int op;
  316.  
  317.     while( (op=getopt(argc, argv, opt_string)) != -1) {
  318.  
  319.     switch (op) {
  320.     case 't':
  321.         terse = 1; 
  322.         break;
  323.     case 's':
  324.         terse=1; 
  325.         line=1; 
  326.         break;
  327.     case 'd':
  328.             print_table(decimal);
  329.             exit(0);
  330.     case 'x':
  331.             print_table(hex);
  332.             exit(0);
  333.     case 'o':
  334.             print_table(octal);
  335.             exit(0);
  336.     case '?':
  337.     case 'h':
  338.         help = 1;
  339.         break;
  340.     case 'v':
  341.         printf("ascii %2.1f\n",REVISION); exit(0) ;
  342.         break;
  343.     default :
  344.         help = 1;
  345.         break;
  346.         } /*switch*/
  347.     }/*while*/
  348. }
  349.  
  350. /******************************************************************/
  351. static char *btoa(val)
  352. /* binary-to-ASCII conversion */
  353. {
  354. #define BITSPERCHAR 8
  355.     char    *rp;
  356.     static char rep[BITSPERCHAR + 1];
  357.  
  358.     /* write out external representation at least one char */
  359.     *(rp = rep + BITSPERCHAR) = '\0';
  360.     do {
  361.        *--rp = (val & 1) + '0'; /* Is '1' == '0' + 1 in EBCDIC? */
  362.        val /= 2;
  363.     } while
  364.     (val && rp > rep);
  365.  
  366. #ifndef SHORT_BINARY_REPRESENTATION
  367.     while (rp > rep)
  368.        *--rp = '0';
  369. #endif
  370.  
  371.     return(rp);
  372. }
  373.  
  374. /******************************************************************/
  375. static void speak(ch)
  376. /* list all the names for a given character */
  377. int ch;
  378. {
  379.     char    **ptr = &cnames[ch][0];
  380.  
  381.     if (terse) {
  382.         (void) printf("%d/%d   %d   0x%02X   0o%o   %s\n", 
  383.               ch / 16, ch % 16, ch, ch, ch, btoa(ch));
  384.         return;
  385.     }
  386.  
  387.     (void) printf(
  388.     "ASCII %d/%d is decimal %03d, hex %02x, octal %03o, bits %s: ",
  389.     ch / 16, ch % 16, ch, ch, ch, btoa(ch));
  390.  
  391.     /* display high-half characters */
  392.     if (ch & 0x80)
  393.     {
  394.     ch &=~ 0x80;
  395.     if (ch == 0x7f)
  396.         (void) printf("meta-^?\n");
  397.     else if (isprint(ch))
  398.         (void) printf("meta-%c\n", ch);
  399.     else
  400.         (void) printf("meta-^%c\n", '@' + (ch & 0x1f));
  401.     return;
  402.     }
  403.  
  404.     if (isprint(ch))
  405.     (void) printf("prints as `%s'\n", *ptr++);
  406.     else if (iscntrl(ch) || ch == 0x7F)
  407.     {
  408.     if (ch == 0x7f)
  409.         (void) printf("called ^?");
  410.     else
  411.         (void) printf("called ^%c", '@' + (ch & 0x1f));
  412.     for (; strlen(*ptr) < 4 && isupper(**ptr); ptr++)
  413.         (void) printf(", %s", *ptr);
  414.     (void) putchar('\n');
  415.     }
  416.  
  417.     (void) printf("Official name: %s\n", *ptr++);
  418.  
  419.     if (*ptr)
  420.     {
  421.     char    *commentary = (char *)NULL;
  422.  
  423.     if (**ptr == '\\')
  424.     {
  425.         (void) printf("C escape: '%s'\n", *ptr);
  426.         ptr++;
  427.     }
  428.  
  429.     (void) printf("Other names: ");
  430.     for (; *ptr; ptr++)
  431.         if (**ptr == '#')
  432.         commentary = *ptr;
  433.         else
  434.         (void) printf("%s%s ", *ptr, 
  435.                   (ptr[1] && *ptr[1] != '#') ? "," : "");
  436.     (void) putchar('\n');
  437.     if (commentary)
  438.         (void) printf("Note: %s\n", commentary+2);
  439.     }
  440.  
  441.     (void) putchar('\n');
  442. }
  443. /******************************************************************/
  444. static void ascii(str)
  445. char *str;
  446. {
  447.     int ch, hi, lo;
  448.     char **ptr;
  449.     int len = strlen(str);
  450.  
  451.     /* interpret single characters as themselves */
  452.     if (len == 1)
  453.        { speak(str[0]); return; }
  454.  
  455.     /* process multiple letters */ 
  456.     if (line == 1) {    
  457.     for (ch = 0; ch < len; ch ++) {
  458.         speak(str[ch]);
  459.     }
  460.     return;
  461.     }
  462.  
  463.     /* interpret ^-escapes as control-character notation */
  464.     if (strcmp(str, "^?") == 0)
  465.          { speak(0x7F); return; } 
  466.     else if (str[0] == '^' && len == 2)
  467.      { speak(str[1] & 0x1f); return; }
  468.  
  469.     /* interpret C-style backslash escapes */
  470.     if (*str == '\\' &&  len == 2 && strchr("abfnrtv", str[1]))
  471.     for (ch = 7; ch < 14; ch++)
  472.         for (ptr = &cnames[ch][1]; *ptr; ptr++)
  473.         if (**ptr == '\\' && strcmp(str, *ptr) == 0)
  474.             { speak(ch); return; }
  475.  
  476.     /* interpret 2 and 3-character ASCII control mnemonics */
  477.     if (len == 2 || len == 3)
  478.     {
  479.     /* first check for standard mnemonics */
  480.     if (stricmp(str, "DEL") == 0)
  481.         { speak(0x7f); return; }
  482.     if (stricmp(str, "BL") == 0)
  483.         { speak(' '); return; }
  484.     else if (isalpha(str[0]))
  485.         for (ch = 0; ch <= 32; ch++)
  486.         if (!stricmp(str,cnames[ch][0]) || !strcmp(str,cnames[ch][1]))
  487.             { speak(ch); return; }
  488.     }
  489.  
  490.     /* OK, now try to interpret the string as a numeric */
  491.     if (len > 1 && len < 9)
  492.     {
  493.     int hval, dval, oval, bval, spoken = 0;
  494.  
  495.     dval = oval = hval = bval = -1;
  496.  
  497.     /* if it's all numeric it could be in one of three bases */
  498.     if (len <= 2 && strspn(str,"0123456789ABCDEFabcdef") == len)
  499.         (void) sscanf(str, "%x", &hval);
  500.     if (len <= 3 && strspn(str, "0123456789") == len)
  501.         (void) sscanf(str, "%d", &dval);
  502.     if (len <= 3 && strspn(str, "01234567") == len)
  503.         (void) sscanf(str, "%o", &oval);
  504.     if (len <= 9 && strspn(str, "01") == len)
  505.         bval = atob(str);
  506.  
  507.     /* accept 0xnn, \xnn, xnn and nnh forms for hex */
  508.     if (hval == -1)
  509.         if ((str[0]=='0'||str[0]=='\\') && tolower(str[1]) == 'x')
  510.         (void) sscanf(str + 2, "%x", &hval);
  511.         else if (tolower(str[0]) == 'x')
  512.         (void) sscanf(str + 1, "%x", &hval);
  513.         else if ((len >= 2) && (len <= 3) &&
  514.             (strspn(str,"0123456789ABCDEFabcdef") == (len-1)) &&
  515.             (tolower(str[len - 1]) == 'h'))
  516.         (void) sscanf(str, "%x", &hval);
  517.  
  518.     /* accept 0onn, \onnn, onnn and \nnn forms for octal */
  519.     if (oval == -1)
  520.         if ((str[0]=='0'||str[0]=='\\') && tolower(str[1]) == 'o')
  521.         (void) sscanf(str + 2, "%o", &oval);
  522.         else if (tolower(str[0]) == 'o')
  523.         (void) sscanf(str + 1, "%o", &oval);
  524.         else if (str[0] == '\\' && strspn(str + 1, "0123456789") == len - 1)
  525.         (void) sscanf(str + 1, "%o", &oval);
  526.  
  527.     /* accept 0dnnn, \dnnn and dnnn forms for decimal */
  528.     if (dval == -1)
  529.         if ((str[0]=='0'||str[0]=='\\') && tolower(str[1]) == 'd')
  530.         (void) sscanf(str + 2, "%d", &dval);
  531.         else if (tolower(str[0]) == 'd')
  532.         (void) sscanf(str + 1, "%d", &dval);
  533.  
  534.     /* accept 0bnnn, \bnnn and bnnn forms for binary */
  535.     if (bval == -1)
  536.         if ((str[0]=='0'||str[0]=='\\') && tolower(str[1]) == 'b')
  537.         bval = atob(str + 2);
  538.         else if (tolower(str[0]) == 'b')
  539.         bval = atob(str + 1);
  540.  
  541.     /* OK, now output all values */
  542.     if (hval > -1 && hval < 256)
  543.         speak(hval & 0xff);
  544.     if (dval > -1 && dval < 256)
  545.         speak(dval & 0xff);
  546.     if (oval > -1 && oval < 256)
  547.         speak(oval & 0xff);
  548.     if (bval > -1 && bval < 256)
  549.         speak(bval & 0xff);
  550.     if (!(hval==-1 && dval==-1 && oval==-1 && bval==-1))
  551.     {
  552.         if (hval > -1 || dval > -1 || oval > -1 || bval > -1)
  553.         return;
  554.         if (hval < 256 || dval < 256 || oval < 256 || bval < 256)
  555.         return;
  556.     }
  557.     }
  558.  
  559.     if (sscanf(str, "%d/%d", &hi, &lo) == 2)    /* code table reference?  */
  560.     { speak(hi*16 + lo); return; }
  561.     else if (len > 1 && isalpha(str[0]))    /* try to match long names */
  562.     {
  563.     char    canbuf[BUFSIZ], *ep;
  564.     int i;
  565.  
  566.     /* map dashes and other junk to spaces */
  567.     for (i = 0; i <= len; i++)
  568.         if (str[i] == '-' || isspace(str[i]))
  569.         canbuf[i] = ' ';
  570.         else
  571.         canbuf[i] = str[i];
  572.  
  573.     /* strip `sign' or `Sign' suffix */
  574.     ep = canbuf + strlen(canbuf) - 4;
  575.     if (!strcmp(ep, "sign") || !strcmp(ep, "Sign"))
  576.         *ep = '\0';
  577.  
  578.     /* remove any trailing whitespace */
  579.     while (canbuf[strlen(canbuf) - 1] == ' ')
  580.         canbuf[strlen(canbuf) - 1] = '\0';
  581.  
  582.     /* look through all long names for a match */
  583.     for (ch = 0; ch < 128; ch++)
  584.         for (ptr = &cnames[ch][1]; *ptr; ptr++)
  585.         if (!stricmp(*ptr, canbuf))
  586.             speak(ch);
  587.     } /* outer if */
  588. }
  589. /******************************************************************/
  590. void
  591. print_table(unsigned short delivery)
  592. {
  593.    static unsigned short i, j, len;
  594.    char   separator[]= "   "; 
  595.    char   *tail     = separator + 3 ;
  596.    char   *space; 
  597.    char   *name ;
  598.  
  599.    for (i=0;i<16; i++) {
  600.            for (j=0; j<8; j++) {
  601.                   name= *cnames[i+(j*16)];
  602.                   len = strlen(name);
  603.                   space = tail - (len % 3) ; 
  604.                   switch (delivery) {
  605.                       case decimal:  printf("%5d %1s%1s",i+(j*16),name,space);
  606.                                      break;
  607.                       case octal  :  printf("%5o %1s%1s",i+(j*16),name,space);
  608.                                      break;
  609.                       case hex    :  printf("%5X %1s%1s",i+(j*16),name,space);
  610.                                      break;
  611.                   }
  612.            }
  613.            printf("\n");
  614.    }
  615.        
  616. }
  617. /*----------------------------------------- M A I N --------------*/
  618. int main(argc, argv)
  619. int argc;
  620. char **argv;
  621. {
  622.     char      *optstring="tshvxod" ;
  623.  
  624.  
  625.     process_options(argc, argv, optstring) ;
  626.  
  627.     if (help || argc == optind)
  628.     showHelp(stdout, argv[0]);
  629.     else 
  630.     while (optind < argc)       
  631.         ascii(argv[optind++]);
  632.     exit(0);
  633. }
  634. /******************************************************************/
  635. /* ascii.c ends here */
  636.  
  637.